package com.peak.distribution.web.validator;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class ValidateRuleBuilder {

	private List<ValidateRule> rules = Lists.newArrayList();
	
	public static ValidateRuleBuilder create() {
		ValidateRuleBuilder validateRuleBuilder = new ValidateRuleBuilder();
		validateRuleBuilder.rules.add(new ValidateRule());
		return validateRuleBuilder;
	}
	
	public ValidateRuleBuilder and() {
		rules.add(new ValidateRule());
		return this;
	}
	
	public ValidateRuleBuilder rule(String name, String title) {
		ValidateRule rule = rules.get(rules.size() - 1);
		rule.setProptertyName(name);
		rule.setProptertyTitle(title);
		return this;
	}
	
	@SafeVarargs
	public final ValidateRuleBuilder methods(Class<? extends ValidateRuleMethod>... methods) {
		ValidateRule rule = rules.get(rules.size() - 1);
		rule.getMethods().addAll(Arrays.asList(methods));
		return this;
	}
	
	public final MethodParam methodParam(Class<? extends ValidateRuleMethod> method) {
		ValidateRule rule = rules.get(rules.size() - 1);
		MethodParam param = new MethodParam(this, rule, method);
		return param;
	}
	
	public List<ValidateRule> build() {
		return this.rules;
	}
	
	public class MethodParam {
		
		private Class<? extends ValidateRuleMethod> method;
		
		private ValidateRuleBuilder builder;
		
		private ValidateRule rule;

		public MethodParam(ValidateRuleBuilder builder, ValidateRule rule, Class<? extends ValidateRuleMethod> method) {
			super();
			this.builder = builder;
			this.rule = rule;
			this.method = method;
		}
		
		public MethodParam add(String key, Object value) {
			Map<String, Object> params = rule.getMethodParam().get(method);
			if (params == null) {
				params = Maps.newHashMap();
				rule.getMethodParam().put(method, params);
			}
			params.put(key, value);
			return this;
		}
		
		public ValidateRuleBuilder end() {
			return builder;
		}
	}
}
